package com.server.pojo;

import com.alibaba.fastjson2.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.server.libs.login.data.AppCache;
import com.server.libs.ret.RE;
import com.server.pojo.base.PojoBase;
import lombok.*;
import lombok.experimental.Accessors;
import org.hibernate.Hibernate;

import javax.persistence.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Getter
@Setter
@ToString

@Entity
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@Table
public class MobileApp extends PojoBase {

    @Column(unique = true)
    String account;

    @JsonIgnore
    @Column(nullable = false)
    String password;


    String name;
    String sex;
    String tel;
    Integer job;
    String addr;

    public MobileApp update(MobileApp mobileApp){
        name = mobileApp.getName();
        sex = mobileApp.getSex();
        tel = mobileApp.getTel();
        job = mobileApp.getJob();
        addr = mobileApp.getAddr();
        return this;
    }


    /*接受所有*/
    Boolean receivedAll = false;

    Boolean root;

    @Column(unique = true)
    String email;

    /* 设备id */
    String deviceId;

    /* 设备类型 */
    String deviceType;

    String ip;
    Integer port;
    @Column(precision = 13, scale = 10)
    BigDecimal latitude;

    @Column(precision = 13, scale = 10)
    BigDecimal longitude;

    @JSONField(format = "millis")
    Date locationAt;


    @JSONField(format = "millis")
    Date onlineAt;

    /* 当前警报*/
    @ManyToOne
    @JsonIgnore
    @ToString.Exclude
    Alarm nowAlarm;


    @JsonIgnore
    @OneToMany(mappedBy = "mobileApp",cascade = CascadeType.ALL)
    @ToString.Exclude
    List<Alarm> alarms = new ArrayList<>();

    @JsonIgnore
    @OneToMany(mappedBy = "mobileApp",cascade = CascadeType.ALL)
    @ToString.Exclude
    List<MobileAppUnit> mobileAppUnits = new ArrayList<>();


    @JsonIgnore
    @OneToMany(mappedBy = "mobileApp",cascade = CascadeType.ALL)
    @ToString.Exclude
    List<MobileAppAlarm> mobileAppAlarms = new ArrayList<>();

    @JsonIgnore
    @OneToMany(mappedBy = "mobileApp",cascade = CascadeType.ALL)
    @ToString.Exclude
    List<MobileAppTrack> track;

    @JsonIgnore
    @OneToMany(mappedBy = "mobileApp",cascade = CascadeType.ALL)
    @ToString.Exclude
    List<AlarmMessage> alarmMessages;

    @JsonIgnore
    @ToString.Exclude
    @OneToMany(mappedBy = "mobileApp",cascade = CascadeType.ALL)
    List<MobileAppNotice> mobileAppNotices = new ArrayList<>();

    public String getDeviceType() {
        return deviceType != null ? deviceType : "";
    }

    public boolean isHaveLocation(){
        return latitude != null && longitude != null;
    }

    public boolean isOnline(List<AppCache> olineList){
        for (AppCache appCache : olineList) {
            if (Objects.equals(appCache.id, id)) return true;
        }
        return false;
    }


    @JsonIgnore
    public Alarm getNowAlarm() {
        if(nowAlarm==null || nowAlarm.isExpired()){
            nowAlarm = null;
            return null;
        }else {
            return nowAlarm;
        }
    }

    @JsonIgnore
    public List<MobileAppTrack> getTrack() {
        List<MobileAppTrack> var = new ArrayList<>(track);
        var.sort((var1,var2)->Long.compare(var2.getCreatedAt().getTime(),var1.getCreatedAt().getTime()));
        return var;
    }


    @PrePersist
    public void prePersist(){

    }

    @PreUpdate
    public void preUpdate(){
        if (name==null || name.isEmpty())name=account;
        getNowAlarm();
    }

    public void check(){
        checkPassword();
        if(job==null || job == 0)throw new RE("请选择身份");
        if(addr==null || addr.isEmpty())throw new RE("地址不可为空");
    }

    public void checkPassword(){
        if ((account == null || account.contains(" ") || account.isEmpty()) && (password == null || password.contains(" ") || password.isEmpty())) {
            throw new RE("账号或密码异常");
        }
    }


    @PreRemove
    public void preRemove(){


    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false;
        MobileApp mobileApp = (MobileApp) o;
        return getId() != null && Objects.equals(getId(), mobileApp.getId());
    }

    @Override
    public int hashCode() {
        return getClass().hashCode();
    }
}
